package cn.xinfei.xdecision.data.core.frame.check.impl;

import cn.xinfei.xdecision.common.model.datax.datamanage.v2.vo.VariableDTO;
import cn.xinfei.xdecision.common.model.datax.enums.VariableEnum;
import cn.xinfei.xdecision.common.model.datax.exception.XDecisionDataException;
import cn.xinfei.xdecision.common.model.datax.exception.XDecisionDataExceptionType;
import cn.xinfei.xdecision.common.service.datax.datamanage.v2.VariableService;
import cn.xinfei.xdecision.data.core.frame.check.VariableCheck;
import cn.xinfei.xdecision.data.core.frame.executors.groovy.GroovySupport;
import cn.xinfei.xdecision.data.core.util.ExpressionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class VariableCheckService implements VariableCheck {

    @Value("${variable.derive.param.size:0}")
    Integer variableDeriveParamSize;

    @Autowired
    VariableService variableService;

    @Autowired
    GroovySupport groovySupport;

    @Override
    public void checkVarParam(VariableDTO variable) {
        if (VariableEnum.DERIVE_VAR.name().equalsIgnoreCase(variable.getVarType())) {
            if (StringUtils.isBlank(variable.getScript())) {
                throw new XDecisionDataException(
                        XDecisionDataExceptionType.DERIVE_PARAM_SCRIPT_ERROR,
                        "脚本不存在"
                );
            } else {
                //获取变量默认值
                List<String> paramList = new ArrayList<>(variable.getParameterVariables());
                List<VariableDTO> variableDTOS = variableService.findAllByVarCodes(paramList);
                Map<String, Object> map = new HashMap<>();
                try {
                    variableDTOS.forEach(var -> {
                        if (StringUtils.isNotBlank(var.getValueType())) {
                            switch (var.getValueType()) {
                                case "integer":
                                    map.put(var.getVarCode(), Integer.valueOf(var.getDefaultValue()));
                                    break;
                                case "double":
                                    map.put(var.getVarCode(), Double.valueOf(var.getDefaultValue()));
                                    break;
                                case "string":
                                    map.put(var.getVarCode(), var.getDefaultValue());
                                    break;
                                case "boolean":
                                    map.put(var.getVarCode(), Boolean.valueOf(var.getDefaultValue()));

                            }
                        }
                    });
                } catch (Exception e) {
                    log.error("checkParam check default error ", e);
                    throw new XDecisionDataException(
                            XDecisionDataExceptionType.DERIVE_PARAM_DEFAULT_ERROR,
                            "衍生变量未设置默认值异常"
                    );
                }
                try {
                    Object o = groovySupport.parseExpr(variable.getScript(), map);
                    boolean b = ExpressionUtil.resultDataTypeCheck(variable.getValueType(), o);
                    if (!b) {
                        throw new XDecisionDataException(
                                XDecisionDataExceptionType.DERIVE_PARAM_SCRIPT_CHECK_RESULT_ERROR,
                                "表达式返回结果类型不匹配"
                        );
                    }
                } catch (Exception e) {
                    log.error("checkParam check error", e);
                    throw new XDecisionDataException(
                            XDecisionDataExceptionType.DERIVE_PARAM_SCRIPT_CHECK_RESULT_ERROR,
                            "表达式校验异常"
                    );

                }
            }
            if (CollectionUtils.isEmpty(variable.getParameterVariables()) || variable.getParameterVariables().size() > variableDeriveParamSize) {
                throw new XDecisionDataException(
                        XDecisionDataExceptionType.DERIVE_PARAM_INPUT_ERROR,
                        "表达式校验异常"
                );
            }

        }
    }

    @Override
    public void checkUsing(VariableDTO variable) {

        if (VariableEnum.DERIVE_VAR.name().equalsIgnoreCase(variable.getVarType())) {
            //判断变量是否使用

        }
    }
}
